home *** CD-ROM | disk | FTP | other *** search
/ Chip 1996 April / CHIP 1996 aprilis (CD06).zip / CHIP_CD06.ISO / hypertxt.arj / 92 / SZIMU2.CD < prev    next >
Text File  |  1995-09-14  |  16KB  |  437 lines

  1.       @VSzaporodjatok és sokasodjatok...@N
  2.  
  3.       @VSzimuláció 2.@N
  4.  
  5.           Sorozatunk elsô részében tettünk egy kísérletet a nyájas
  6.       Olvasó meggyôzésére: a  szimuláció fontos, érdekes,  mi több
  7.       akár  szórakoztató  is  lehet.  Megismerkedtünk  a folytonos
  8.       keretmodellel,  s  láttunk  két  egyszerû  példát  a  fizika
  9.       területén lehetséges alkalmazásra.
  10.           Ezúttal   bôvíteni  szeretnénk   a  kínálatot,   további
  11.       fogásokat veszünk fel az étlapra.
  12.  
  13.  
  14.       @V""Élünk és meghalunk..."@N
  15.  
  16.           Olvasóink bizonyára találkoztak már egy népesség életkor
  17.       szerinti megoszlását ábrázoló  grafikonnal, a korfával.  Nem
  18.       tanulság  nélküli  egy  ilyen  ábra  elemzése.  A  mellékelt
  19.       grafikonok  (melyek  a PCGlobe  program  segítségével, annak
  20.       adatai alapján készültek) számos érdekességet tartalmaznak.
  21.           Az   ábrák   Németország,   Angola   illetve  Svédország
  22.       népességének  életkor  szerinti  eloszlását  mutatják, nemek
  23.       szerinti  bontásban. Egészen  más képet  mutat egy  ""jóléti
  24.       állam",  egy   --  szegény   --  fejlôdô   ország,  és   egy
  25.       közép-európai ország  korfája. Az  értô szem  rengeteg tényt
  26.       tud  belôlük megállapítani,  még a  közelmúlt történelme  is
  27.       kiolvasható némi szemlélôdés után. A következôkben egy olyan
  28.       modell  vázlatos  leírását  adjuk  meg,  mely  képes  lesz e
  29.       jelenségek szimulálására.
  30.           Gondoskodnunk  kell  arról,  hogy  a  populációt  alkotó
  31.       egyedek  ""megszülessenek",  ""öregedjenek", ""meghaljanak".
  32.       Csupa olyan fogalommal fogunk dolgozni, melyek a  mindennapi
  33.       életbôl    ismertek:    lesznek    generációk,    szülôképes
  34.       korosztályok (hogy  ezt a  ronda terminológiát  használjuk),
  35.       várható életkor stb.  Modellünk elsô változatában  az alábbi
  36.       változókat fogjuk használni:
  37.           @KN@N -- az egyedek száma, azaz a populáció létszáma
  38.           @KK@N -- a korcsoportok, generációk száma
  39.           @KT(I)@N   --   megmutatja,   hogy   az   @KI.@N   egyed  melyik
  40.       korcsoporthoz tartozik
  41.           @KS(J)@N   --   a   @KJ.@N   korcsoport   szaporodási  (szülési)
  42.       valószínûsége
  43.           @KH(J)@N -- a @KJ.@N korcsoport halálozási valószínûsége  (tehát
  44.       @KH(K)=1@N)
  45.           @KDB(J)@N -- a @KJ.@N generáció egyedeinek száma
  46.           Szimulációs   keretmodellünket    (melyet   múlt    havi
  47.       számunkban írtunk  le) három  ponton kell  részleteznünk. Az
  48.       adatbeviteli részben nyilván  ""kézzel" írandók be  @KK, S(J),
  49.       H(J)@N  értékei,  hiszen  ezek  változtatásával  tudunk   majd
  50.       különbözô  futási  eredményeket produkálni.  A  @KT(I)@N értékek
  51.       bevitele  már   kérdéses:  jó   lenne  más   és  más  induló
  52.       feltételeket  beállítani,  de programunk  akkor  érdekes (és
  53.       valószerû),  ha sok  egyeddel dolgozik.  Ehhez azonban  több
  54.       ezer adatot  kellene beírni,  tehát célszerûbb  a kiindulási
  55.       eloszlást véletlenszerûen elôállítani.
  56.           Ekkor    (gépünk/nyelvünk     véletlenszám-generátorától
  57.       függôen) egy  svéd-jellegû eloszlásból  fogunk indulni.  Meg
  58.       kell   gondolnunk,   hogy  milyen   kimenô   adat(ok)ra  van
  59.       szükségünk:  kezdetben  maradjunk  csak  a  kormegoszlásnál,
  60.       melyet  megjeleníthetünk   numerikusan,  de   ízlés  szerint
  61.       grafikusan is.  Ezek után  már csak  a ""szimulációs  lépés"
  62.       megírása van hátra:
  63.           @KSzimulációs_lépés;
  64.           J=N;
  65.           Ciklus I=1-tôl N-ig;
  66.         Ha RND<H(T(I)) akkor
  67.             T(I):=0 {meghalt}
  68.             DB(T(I)):=DB(T(I))-1;
  69.         különben Ha RND<S(T(I)) akkor J:=J+1 {uj}
  70.         T(J):=1
  71.         DB(0):=DB(0)+1
  72.         T(I):=T(I)+1 {öregedés}
  73.         DB(T(I):=DB(T(I))-1
  74.         DB(T(I+1):=DB(T(I+1))+1
  75.           Ciklus vége
  76.           Táblázattömörítés;
  77.           Eljárás vége;@N
  78.           A táblázattömörítés azért szükséges, mert látható  módon
  79.       elôbb-utóbb   igen   sok   nullát   tartanánk   nyilván  (az
  80.       elhalálozott egyedek  helyén), miközben  a szaporodás  miatt
  81.       tömbünk kinôné a rendelkezésére álló helyet.
  82.           @KTáblázattömörítés;
  83.           L:=0;
  84.           Ciklus I:=1-tôl J-ig
  85.         Ha T(I)>0 akkor L:=L+1
  86.         T(L):=T(I)
  87.           Ciklus vége
  88.           N:=L;
  89.           Eljárás vége;@N
  90.           Ezek  után (már  természetesen ha  valamilyen nyelven  a
  91.       programkódot is elôállítottuk) játszhatunk a  feltételekkel:
  92.       növelhetjük,   csökkenthetjük    a   szaporaság    mértékét;
  93.       szélesíthetjük,  szûkíthetjük  a  szülni  képes   generációk
  94.       körét;   beállíthatjuk   mondjuk   a   fiatalkori  halálozás
  95.       mértékét,  és így  tovább. Módunkban  áll járványok  hatását
  96.       megfigyelni: ehhez a  szimulációs lépést ki  kell bôvítenünk
  97.       egy @KJárvány@N nevû eljárással, melynek a lényege az, hogy  egy
  98.       meghatározott, alacsony (@KY@N-nal jelölt) valószínûségû esetben
  99.       a   teljes   népesség  egy   jelentôsebb   (jele  @KZ@N)   része
  100.       megbetegszik és ennek következtében elpusztul. A @KJárvány@N egy
  101.       lehetséges algoritmusa:
  102.           @KJárvány;
  103.         Ha RND<Y akkor Ciklus I:=1-tôl N-ig
  104.                 Ha RND<Z akkor T(I):=0
  105.                 DB(T(I)):=DB(T(I))-1
  106.               Ciklus vége
  107.         Eljárás vége;@N
  108.           Hasonló módon háborúk hatása is vizsgálható, az  eltérés
  109.       mindössze  (a  program szempontjából)  annyi,  hogy bizonyos
  110.       korosztályokra nô meg  a halálozási valószínûség  egy idôre.
  111.       Teljesen analóg módon olyan népesség-politikai  intézkedések
  112.       is modellezhetôk, mint a GYES-GYED bevezetése.
  113.           Ha  a  program  kimeneteként  csak  a  globális adatokra
  114.       vagyunk  kíváncsiak,  az  algoritmus  az  alábbiak   szerint
  115.       jelentôsen     leegyszerûsíthetô.     Természetesen    ennek
  116.       megfelelôen az adatbevitel is kényelmesebb, gyorsabb  lehet.
  117.       (A   változók   jelölése   azonos   az   elsô  algoritmusnál
  118.       alkalmazottakkal):
  119.           @KSzimulációs_lépés_2;
  120.           Ciklus I:=1-tôl K-ig
  121.         Ciklus J:=1-tôl DB(I)-ig
  122.           Ha RND<H(I) akkor DB(I):=DB(I)-1
  123.           különben Ha RND<S(I) akkor D(0):=D(0)+1
  124.         Ciklus vége
  125.           Ciklus vége
  126.           Ciklus L:=K-1-tôl 0-ig
  127.         DB(L+1):=DB(L)
  128.           Ciklus vége
  129.           DB(0):=0
  130.           Eljárás vége;@N
  131.  
  132.  
  133.       @VKüzdelem az életért@N
  134.  
  135.           Az eddigiekben egy faj egyedeivel foglakoztunk, a  külsô
  136.       tényezôket   korlátozottan   vettük   figyelembe.   Pedig  a
  137.       növekedésnek  korlátai  vannak: a  túlnépesedés,  a táplálék
  138.       véges  mennyisége,  ""ellenséges"   --  ragadozó  --   fajok
  139.       jelenléte, stb.  A továbbiakban  Eigen, Nobel-díjas  kémikus
  140.       már említett könyve (M. Eigen: A játék) alapján néhány olyan
  141.       játékot  ismertetünk,  melyek a  szelekció,  a fajok  egymás
  142.       mellett élésének megértéséhez visznek közelebb.
  143.           Ezek a játékok táblán, dobókockával játszandók,  elvileg
  144.       nincs  szükség  számítógépre.  Látni  fogjuk  azonban,  hogy
  145.       technikai  nehézségekbe  ütköznénk, hiszen  több  száz, vagy
  146.       ezer dobást kellene  végrehajtanunk, mondjuk oktaéder  alakú
  147.       kockával.   Másrészt   --   lévén   a   játékoknak  pontosan
  148.       megfogalmazott  szabályrendszerük  --  nem  okoz  nehézséget
  149.       számítógépre  való  átírásuk  és  így  elérhetô  például   a
  150.       mintanagyság növelése is. Csak javasolni tudjuk  mindenkinek
  151.       az   átírást:   megdöbbentôen   jól   modellezik   a   valós
  152.       jelenségeket ezek az igen egyszerû szabályokkal definiálható
  153.       játékok.
  154.  
  155.  
  156.       @VKiválasztódás@N
  157.  
  158.           Négyzet   alakú   táblán   játszunk,   melyet  kezdetben
  159.       ""feltöltünk" különbözô  színû (az  egyszerûbb esetben  csak
  160.       két színt  használva) golyókkal.  Ekkor indulnak  a dobások,
  161.       melyek  során  --  szigorúan  váltakozva  --  két   szabályt
  162.       alkalmazunk:
  163.           1. A kisorsolt mezôn lévô golyót levesszük a tábláról.
  164.           2.  A ""megcímzett"  golyót megduplázzuk,  azaz a  tábla
  165.       üres helyére vele azonos színût helyezünk.
  166.           Ezt  egészen  addig  ismételjük,  míg  az  egész   tábla
  167.       egyszínûvé válik.  Érdekesebbé tehetô  a játék,  ha az egyes
  168.       színekhez más szelekciós esélyt rendelünk. Ez megvalósítható
  169.       a  koordináta-sorsolás  utáni  újabb  kockadobással, melynek
  170.       eredményétôl  függôen  veszünk  le  illetve  duplázunk   meg
  171.       bizonyos színû golyókat.
  172.           Például a  zöld golyót  csak akkor  távolítjuk el,  ha a
  173.       ""segéddobás" értéke  1, minden  más eredmény  (2..6) esetén
  174.       duplázunk, s mondjuk a kék golyó esetén pont fordítva járunk
  175.       el. A játékban mindig egy szín nyer, de nem biztos, hogy  ez
  176.       a  legnagyobb szelekciós  elônnyel rendelkezô  szín! A  nagy
  177.       elôny kiegyenlíthetô egyenlôtlen kiindulási helyzettel,  ami
  178.       összhangban van azzal a tapasztalattal, hogy ""nagy  értékû"
  179.       mutánsok a természetben is ritkán fordulnak elô.
  180.  
  181.  
  182.       @VTúlélés@N
  183.  
  184.           Szintén koordinátázott, négyzet alakú tábla szükséges  a
  185.       játékhoz,   melyet    némileg   leegyszerûsített    formában
  186.       ismertetünk,  a könnyebb  gépi megvalósíthatóság  érdekében.
  187.       (Az  eredeti  változathoz  tényleges,  taktikázó, gondolkodó
  188.       játékosok kellenek.) A  játékosok különbözô színû  golyókkal
  189.       rendelkeznek  és  ""dobásokkal"  mezôket  sorsolnak  ki.   A
  190.       következô esetek lehetségesek:
  191.           1. A mezô üres, akkor egy saját golyó azon  elhelyezhetô
  192.       (születés).
  193.           2. Ha  a kisorsolt  mezôn saját  golyó van,  akkor addig
  194.       dobhat újra, míg egy  olyan kockára nem talál,  melyen nincs
  195.       saját gombja (reprodukció).
  196.           3.  ""Ellenséges"  mezôt  találva,  az  ott  lévô  golyó
  197.       levehetô, hacsak az nincs túlélô helyzetben (halál).
  198.           4.  Ha  négy  azonos színû  golyó  egy  négyzetes tömböt
  199.       alkot, akkor túlélô helyzet  jött létre, azaz ezek  a golyók
  200.       akkor sem ""halnak meg", ha az ellenfél által kisorsolódnak.
  201.           A játék  akkor ér  véget, ha  minden golyó  ""túlélô", s
  202.       nyilván az  nyert, akinek  a legtöbb  golyóbisa található  a
  203.       táblán.
  204.  
  205.  
  206.       @VKüzdelem@N
  207.  
  208.           Ennek a játéknak Marx György által leírt (Marx György: A
  209.       természet  játékai)  változatát  ismertetjük,  az Eigen-féle
  210.       eredetinél  szemléletesebb  kerettörténete,   játékszabályai
  211.       miatt. Világunk  ismét egy  @KNxN@N-es sakktábla,  ahol káposzta
  212.       nô,  melyet  a  nyulak  fogyasztanak,  de  a  nyulakra rókák
  213.       vadásznak. A játék  kezdetén világunkat valamilyen  eloszlás
  214.       szerint benépesítjük @KK, N, R@N betûkkel (vagy aki teheti, neki
  215.       tetszô  színekkel).  Ekkor  indul  a  ""történelem",  azaz a
  216.       négyzetek  kisorsolása  egymás után.  A  kisorsolt négyzeten
  217.       végrehajtjuk  az alábbi  játékszabályok által  meghatározott
  218.       eseményt:
  219.           1. Ha a négyzet üres, rajta káposzta nô.
  220.           2.  Ha a  négyzeten káposzta  van, s  a négy  szomszédos
  221.       négyzet egyikén sincs nyúl, a káposzta marad.
  222.           3. Ha a kisorsolt négyzeten káposzta van, és  valamelyik
  223.       szomszédos  négyzeten  található   nyúl,  akkor  megeszi   a
  224.       káposztát, s  immár jóllakottan  szaporodik, azaz  a @KK@N  betû
  225.       helyére @KN@N kerül.
  226.           4. Ha a kiválasztott négyzeten nyúl ül és a  szomszédban
  227.       nincs róka,  de van  káposzta, akkor  a nyúl  elfogyasztja a
  228.       káposztát (@KN@N marad, @KK@N eltûnik).
  229.           5. Ha a kidobott négyzeten nyúl van, de a  szomszédokban
  230.       se káposzta, se róka, akkor  a nyúl éhenhal, azaz az  @KN@N betû
  231.       eltûnik.
  232.           6. Ha a négyzeten nyulat találunk, és a szomszédos mezôk
  233.       valamelyikén  róka van,  akkor a  róka a  nyulat megeszi,  s
  234.       ""odaszaporodik" a helyére (@KN@N helyébe @KR@N kerül).
  235.           7.  Ha  az aktuális  mezôn  róka van,  és  a szomszédban
  236.       található egy tapsifüles, akkor  a róka életben marad,  de a
  237.       szegény nyúl nem (@KR@N marad, @KN@N eltûnik).
  238.           8. Ha a sorsolt mezôn róka lakik, de a szomszédban nincs
  239.       nyúl, a róka éhenhal (@KR@N törlendô).
  240.           A  fenti  szabályokat  valósítja  meg  a  listán látható
  241.       Pascal nyelvû program.
  242.           A betûk váltakozása nem igazán informatív,  látványosabb
  243.       eredményt   kapunk,   ha   szimulált   világunk  történéseit
  244.       grafikonon jelenítjük meg,  egymásra vetítve az  egyes fajok
  245.       ""lélekszámát".  Látható a  fajok egymásra  utaltsága --  az
  246.       egyes  görbék  ciklikusan hullámzanak.  A  sok káposzta  sok
  247.       nyulat eredményez, de ez a káposzta mennyiségére van  drámai
  248.       hatással, ami viszont a nyulak pusztulásához vezet.  Eközben
  249.       elszaporodtak  a  rókák  is (volt  sok  nyúl),  de a  nyulak
  250.       pusztulása (melyben a rókák aktív szerepet játszottak) saját
  251.       végüket is jelenti. Igazán  figyelemre méltó a dologban  az,
  252.       hogy a  talán gyermekdednek  tûnô játék  által szolgáltatott
  253.       grafikon mennyire pontosan fedi  a valóságot: a Hudson  Öböl
  254.       Társaság  által  begyûjtött  róka-  és  nyúlprémek  számának
  255.       ingadozása (közel 100 évre visszamenôleg) pontosan ilyen.
  256.           Sorozatunk   következô    részében   kicsit    mélyebben
  257.       vizsgáljuk  az  Eigen-féle   játékok  tartalmát,  az   egyes
  258.       növekedési modelleket, illetve az együttélésre készítünk egy
  259.       másfajta szimulációt.
  260.  
  261.       @KBánhegyesi Zoltán@N
  262.  
  263. {$R-,S-}
  264. program nyul_roka_fu;
  265. {Lencsés&Schmideg}
  266.  
  267. uses crt,graph;
  268. const mx=20; my=20;
  269.       ii:array[1..4,1..2] of shortint = ((0,1),(-1,0),(1,0),(-1,0));
  270. var d,i,j,r,n,f,ti,x,y,k,coun,xe,ye,gd,gm:integer;
  271.     t:array[1..mx,1..my] of char;
  272.     c,ca:char;
  273.     graf:boolean;
  274.  
  275. procedure cha(x,y:integer; duma:string);
  276. begin
  277.   gotoxy(x,y);
  278.   writeln(duma);
  279. end;
  280.  
  281. procedure cha2(x,y:integer; duma:integer);
  282. begin
  283.   gotoxy(x,y);
  284.   writeln(duma,' ');
  285. end;
  286.  
  287. procedure kepuj;
  288. begin
  289.   cha2(48,3,ti);
  290.   cha2(48,5,r);
  291.   cha2(48,7,n);
  292.   cha2(48,9,f);
  293. end;
  294.  
  295. procedure kep;
  296. begin
  297.   for i:=1 to mx do
  298.     for j:=1 to my do cha(i,j,t[i,j]);
  299.   cha(40,1,'Róka - Nyúl - Fû');
  300.   cha(30,3,'Idô   : ');
  301.   cha(30,5,'Rókák száma  : ');
  302.   cha(30,7,'Nyulak száma : ');
  303.   cha(30,9,'Fû     : ');
  304.   cha2(60,5,r);
  305.   cha2(60,7,n);
  306.   cha2(60,9,f);
  307. end;
  308.  
  309. function xx(xe,ye:integer):char;
  310. begin
  311.   if xe=0 then xe:=20;
  312.   if ye=0 then ye:=20;
  313.   if xe=21 then xe:=1;
  314.   if ye=21 then ye:=1;
  315.   xx:=t[xe,ye];
  316. end;
  317.  
  318. procedure szomszed(x,y:integer; ker:char; var k:integer);
  319. begin
  320.   k:=0;
  321.   repeat
  322.     k:=k+1;
  323.   until (xx(x+ii[k,1],y+ii[k,2])=ker) or (k>4);
  324. end;
  325.  
  326. procedure grafikon;
  327. begin
  328.   coun:=coun+1;
  329.   if coun>70 then begin
  330.     cleardevice;
  331.     coun:=1;
  332.    end;
  333.   outtextxy(coun*10,320-r,'R');
  334.   outtextxy(coun*10,320-n,'N');
  335.   outtextxy(coun*10,320-f,'F');
  336. end;
  337.  
  338. procedure szim;
  339. begin
  340.   x:=random(mx)+1;
  341.   y:=random(my)+1;
  342.   case t[x,y] of
  343.     ' ' : begin
  344.         t[x,y]:='F'; cha(x,y,t[x,y]);
  345.         f:=f+1;
  346.       end;
  347.     'F' : begin
  348.         szomszed(x,y,'N',k);
  349.         if k<5 then begin
  350.           t[x,y]:='N'; cha(x,y,t[x,y]);
  351.           f:=f-1; n:=n+1;
  352.         end;
  353.       end;
  354.     'N' : begin
  355.         szomszed(x,y,'R',k);
  356.         if k<5 then begin
  357.           t[x,y]:='R'; cha(x,y,t[x,y]);
  358.           r:=r+1; n:=n-1;
  359.         end
  360.         else begin
  361.           szomszed(x,y,'F',k);
  362.           if k<5 then begin
  363.         t[x+ii[k,1],y+ii[k,2]]:=' ';
  364.         cha(x+ii[k,1],y+ii[k,2],' ');
  365.         f:=f-1;
  366.           end
  367.           else begin
  368.         t[x,y]:=' '; cha(x,y,t[x,y]);
  369.         n:=n-1;
  370.           end;
  371.         end;
  372.       end;
  373.     'R' : begin
  374.         szomszed(x,y,'N',k);
  375.         if k<5 then begin
  376.           t[x+ii[k,1],y+ii[k,2]]:=' ';
  377.           cha(x+ii[k,1],y+ii[k,2],' ');
  378.           n:=n-1;
  379.         end
  380.         else begin
  381.           t[x,y]:=' '; cha(x,y,t[x,y]);
  382.           r:=r-1;
  383.         end;
  384.       end;
  385.   end;
  386.   if graf=true then grafikon else kepuj;
  387. end;
  388.  
  389. procedure bevitel;
  390. begin
  391.   clrscr;
  392.   write('Rókák száma :='); readln(r);
  393.   write('Nyulak száma :='); readln(n);
  394.   write('Fûvek száma :='); readln(f);
  395.   ti:=0;
  396. end;
  397.  
  398. procedure berak(ca:char;d:integer);
  399. begin
  400.    for i:=1 to d do begin
  401.     repeat
  402.       x:=random(mx+1);
  403.       y:=random(my+1);
  404.     until t[x,y]=' ';
  405.     t[x,y]:=ca;
  406.   end;
  407. end;
  408.  
  409. procedure feltolt;
  410. begin
  411.   for i:=1 to mx do
  412.       for j:=1 to my do t[i,j]:=' ';
  413.   berak('F',f);
  414.   berak('N',n);
  415.   berak('R',r);
  416.   write('Grafikonon? (I/N)');
  417.   c:=readkey;
  418.   if (c='I') or (c='i') then begin
  419.                   graf:=true;
  420.                   gd:=0; gm:=0;
  421.                   initgraph(gd,gm,'d:\tp\bgi');
  422.                   write(chr(7));
  423.                  end
  424.              else graf:=false;
  425. end;
  426.  
  427. begin
  428.   graf:=false;
  429.   bevitel;
  430.   feltolt;
  431.   kep;
  432.   repeat
  433.     szim;
  434.     ti:=ti+1;
  435.   until (r<1) or (f<1) or (n<1);
  436. end.
  437.